package com.enki.cigarettes.controller;

import com.enki.cigarettes.controller.vo.request.OrderRequestVo;
import com.enki.cigarettes.controller.vo.response.InitOrderResponseVo;
import com.enki.cigarettes.entity.*;
import com.enki.cigarettes.enums.*;
import com.enki.cigarettes.handler.Response;
import com.enki.cigarettes.repository.*;
import com.enki.cigarettes.statics.StaticKeys;
import com.enki.cigarettes.utils.PrimaryKey;
import com.enki.cigarettes.utils.primary.SnowflakeIdUtil;
import com.enki.cigarettes.utils.wechatpay.WXJSAPIPayConfigImpl;
import com.enki.cigarettes.utils.wechatpay.WXParam;
import com.enki.cigarettes.utils.wechatpay.pay.sdk.WXPay;
import com.enki.cigarettes.utils.wechatpay.pay.sdk.WXPayUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * @author WCS.Wang
 * @version V1.0
 * @Package com.enki.cigarettes.controller
 * @Name e-cigarettes-shop-api-module
 * @Description: TODO 订单逻辑层
 * @date 2019-07-21
 */
@RestController
@RequestMapping("/api/orders")
@Slf4j
public class OrderController {

    @Autowired
    OrderTRepository orderTRepository;
    @Autowired
    OrderItemTRepository orderItemTRepository;
    @Autowired
    CartTRepository cartTRepository;
    @Autowired
    ProductTRepository productTRepository;
    @Autowired
    ProductSkuTRepository productSkuTRepository;
    @Autowired
    TradeSnapshotTRepository tradeSnapshotTRepository;
    @Autowired
    StoreTRepository storeTRepository;
    @Autowired
    DeliverAddressTRepository deliverAddressTRepository;
    @Autowired
    UserCouponTRepository userCouponTRepository;
    @Autowired
    CouponTRepository couponTRepository;
    @Autowired
    UserTRepository userTRepository;
    @Autowired
    BalanceHistoryTRepository balanceHistoryTRepository;

    // H5支付
    private WXJSAPIPayConfigImpl wxjsapiPayConfig;

    public OrderController() throws Exception {
        wxjsapiPayConfig = WXJSAPIPayConfigImpl.getInstance();
    }

    @ApiOperation(value = "初始化订单")
    @ApiImplicitParam(name = "id", value = "购物车ID，使用','拼接", dataType = "String", required = true)
    @GetMapping(value = "/init/{id}")
    public Object initOrder(@PathVariable String id, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            String[] cartIds = id.split(StaticKeys.SPLIT);
            // 总金额
            int totalAmount = 0;
            // 优惠金额
            int discountAmount = 0;
            // 应支付金额
            int shouldAmount = 0;
            Map<String, Object> responseData = new HashMap<>();
            List<InitOrderResponseVo> initOrderVos = new ArrayList<>();
            for (String cartId : cartIds) {
                // 店铺实付金额
                int realPrice = 0;
                CartT cartBean = cartTRepository.findOneByIdAndUserTId(cartId, sessionId.toString());
                if (cartBean != null) {
                    ProductT productBean = productTRepository.findOneByIdAndStatus(cartBean.getProductTId(), ProductEnums.ProductStatus.ONTHSHELF.getType());
                    // 如果此商品不存在跳出当前循环
                    if (productBean == null) {
                        continue;
                    }
                    ProductSkuT productSkuBean = productSkuTRepository.findOneByIdAndStatus(cartBean.getProductSkuTId(), ProductEnums.ProductSkuStatus.ONTHESHELF.getType());
                    // 如果此商品sku不存在跳出当前循环
                    if (productSkuBean == null) {
                        continue;
                    }
                    InitOrderResponseVo initOrderVo = new InitOrderResponseVo();
                    initOrderVo.setId(cartBean.getId());
                    initOrderVo.setName(productBean.getName());
                    initOrderVo.setSkuPicture(productSkuBean.getSkuPicture());
                    initOrderVo.setProductSkuName(productSkuBean.getProductSkuAttrValName());
                    initOrderVo.setProductTId(String.valueOf(productBean.getId()));
                    initOrderVo.setProductSkuTId(cartBean.getProductSkuTId());
                    initOrderVo.setQuantity(cartBean.getQuantity());
                    initOrderVo.setDealPrice(Double.valueOf(productSkuBean.getSalePrice()) / StaticKeys.DISCOUNT_CALCULATION + "");
                    initOrderVo.setTotalPrice(Double.valueOf(cartBean.getQuantity() * productSkuBean.getSalePrice()) / StaticKeys.DISCOUNT_CALCULATION + "");
                    initOrderVo.setRealPrice(Double.valueOf(cartBean.getQuantity() * productSkuBean.getSalePrice()) / StaticKeys.DISCOUNT_CALCULATION + "");
                    initOrderVos.add(initOrderVo);
                    realPrice += cartBean.getQuantity() * productSkuBean.getSalePrice();
                    totalAmount += realPrice;
                }
            }
            // 应支付金额
            shouldAmount = totalAmount - discountAmount;
            final int checkRealPrice = shouldAmount;
            Specification<UserCouponT> specification = new Specification<UserCouponT>() {
                @Override
                public Predicate toPredicate(Root<UserCouponT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    Root<CouponT> couponTRoot = query.from(CouponT.class);
                    predicateList.add(criteriaBuilder.equal(root.get("userId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(root.get("status"), false));
                    predicateList.add(criteriaBuilder.equal(couponTRoot.get("id"), root.get("couponTId")));
                    predicateList.add(criteriaBuilder.equal(couponTRoot.get("status"), true));
                    predicateList.add(criteriaBuilder.greaterThan(couponTRoot.get("effectiveEndTime"), new Date()));
                    predicateList.add(criteriaBuilder.lessThanOrEqualTo(couponTRoot.get("couponMoney"), checkRealPrice));
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            List<UserCouponT> couponBeanList = userCouponTRepository.findAll(specification);
            responseData.put("initOrderVos", initOrderVos);
            responseData.put("totalAmount", Double.valueOf(totalAmount) / StaticKeys.DISCOUNT_CALCULATION + "");
            responseData.put("discountAmount", Double.valueOf(discountAmount) / StaticKeys.DISCOUNT_CALCULATION + "");
            responseData.put("shouldAmount", Double.valueOf(shouldAmount) / StaticKeys.DISCOUNT_CALCULATION + "");
            responseData.put("totalCoupon", couponBeanList.size());
            return Response.success(responseData, StaticKeys.SUCCESS);
        } catch (Exception e) {
            log.error("初始化订单失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，初始化订单失败");
        }
    }

    @ApiOperation(value = "提交订单")
    @PostMapping
    @Transactional
    public Object saveOrder(@RequestBody OrderRequestVo item, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            // 购物车ID集合
            String[] cartIds = item.getCartIds().split(StaticKeys.SPLIT);
            // 支付唯一标识
            String orderPayMenId = SnowflakeIdUtil.getSnowflakeId().nextId() + "";
            List<OrderT> orderItems = new ArrayList<>();
            List<OrderItemT> orderItemItems = new ArrayList<>();
            List<TradeSnapshotT> tradeSnapshotItems = new ArrayList<>();
            List<CartT> delCartItems = new ArrayList<>();
            List<UserCouponT> userCouponItems = new ArrayList<>();
            Map<String, List<CartT>> cartMap = new HashMap<>();
            for (String str : cartIds) {
                CartT cartBean = cartTRepository.findOneByIdAndUserTId(str, sessionId.toString());
                if (cartBean != null) {
                    delCartItems.add(cartBean);
                    if (cartMap.get(cartBean.getStoreTId()) != null) {
                        List<CartT> storeCartItems = cartMap.get(cartBean.getStoreTId());
                        storeCartItems.add(cartBean);
                        cartMap.put(cartBean.getStoreTId(), storeCartItems);
                    } else {
                        List<CartT> storeCartItems = new ArrayList<>();
                        storeCartItems.add(cartBean);
                        cartMap.put(cartBean.getStoreTId(), storeCartItems);
                    }
                }
            }
            // 处理优惠券信息
            int couponDiscount = 0;
            UserCouponT userCoupon = userCouponTRepository.findOneByIdAndUserId(item.getCouponId(), sessionId.toString());
            if (userCoupon != null) {
                CouponT coupon = couponTRepository.findOneById(userCoupon.getCouponTId());
                if (coupon != null) {
                    couponDiscount = coupon.getCouponPrice();
                    userCoupon.setStatus(true);
                    userCoupon.setDataId(orderPayMenId);
                    userCouponItems.add(userCoupon);
                }
            }


            // 迭代处理订单信息
            for (String storeKey : cartMap.keySet()) {
                // 订单编号
                String orderId = SnowflakeIdUtil.getSnowflakeId().nextId() + "";
                // 运费金额
                int storeFreightAmount = 0;
                // 优惠金额
                int storeDiscountAmount = 0;
                // 店铺应支付金额
                int storeShouldAmount = 0;
                // 店铺实付金额
                int realPrice = 0;
                // 店铺总金额
                int storeTotalAmount = 0;
                StoreT store = storeTRepository.findOneById(storeKey);
                if (store != null) {
                    /**
                     * 从Map对象中根据storeID取出购物车集合(要结算的商品在购物车的id集合)
                     */
                    List<CartT> cartItems = cartMap.get(storeKey);
                    for (CartT cartItem : cartItems) {
                        ProductT productBean = productTRepository.findOneByIdAndStatus(cartItem.getProductTId(), ProductEnums.ProductStatus.ONTHSHELF.getType());
                        // 如果此商品不存在跳出当前循环
                        if (productBean == null) {
                            continue;
                        }
                        ProductSkuT productSkuBean = productSkuTRepository.findOneByIdAndStatus(cartItem.getProductSkuTId(), ProductEnums.ProductSkuStatus.ONTHESHELF.getType());
                        // 如果此商品sku不存在跳出当前循环
                        if (productSkuBean == null) {
                            continue;
                        }
                        //要进行结算的商品价格累计
                        //数量 * 售价 - 单价*折扣
                        storeTotalAmount += cartItem.getQuantity() * productSkuBean.getSalePrice();
                        realPrice += cartItem.getQuantity() * productSkuBean.getSalePrice();
                        // 订单条目表
                        OrderItemT orderItem = new OrderItemT();
                        orderItem.setId(PrimaryKey.get().toString());
                        orderItem.setOrderTId(orderId);
                        orderItem.setProductSkuTId(productSkuBean.getId());
                        orderItem.setProductTId(productBean.getId());
                        orderItem.setProductSnapshotTId(StaticKeys.NULL);
                        orderItem.setQuantity(cartItem.getQuantity());
                        orderItem.setProductPrice(productSkuBean.getSalePrice());
                        orderItem.setProductSkuName(productSkuBean.getProductSkuAttrValName());
                        // 处理sku名称
                        orderItem.setSubtotal(cartItem.getQuantity() * productSkuBean.getSalePrice());
                        orderItem.setRemark(StaticKeys.NULL);
                        // 评论状态
                        orderItem.setCreateTime(new Date());
                        // 是否申请售后服务
                        orderItem.setAfterItemStatus(false);
                        // 活动ID
                        orderItem.setActivityTId(StaticKeys.NULL);
                        // 活动商品ID
                        orderItem.setActivityProductsTId(StaticKeys.NULL);
                        orderItemItems.add(orderItem);
                        /*
                         * 交易快照表
                         */
                        TradeSnapshotT tradeSnapshot = new TradeSnapshotT();
                        tradeSnapshot.setId(PrimaryKey.get().toString());
                        tradeSnapshot.setOrderItemTId(orderItem.getId());
                        tradeSnapshot.setOrderTId(orderId);
                        tradeSnapshot.setProductTId(productBean.getId());
                        tradeSnapshot.setSkuCode(productSkuBean.getSkuCode());
                        tradeSnapshot.setName(productBean.getName());
                        tradeSnapshot.setPrice(productSkuBean.getPrice());
                        tradeSnapshot.setMemberPrice(productSkuBean.getMemberPrice());
                        tradeSnapshot.setSalePrice(productSkuBean.getSalePrice());
                        tradeSnapshot.setSelf(true);
                        tradeSnapshot.setProductCode(productSkuBean.getProductCode());
                        tradeSnapshot.setStatus(productBean.getStatus());
                        tradeSnapshot.setStoreTId(storeKey);
                        tradeSnapshot.setSummary(productSkuBean.getSummary());
                        tradeSnapshot.setProductSkuDetail(productSkuBean.getProductSkuDetail());
                        tradeSnapshot.setProductSkuMobileDetail(productSkuBean.getProductSkuMobileDetail());
                        tradeSnapshot.setProductSkuAttrId(productSkuBean.getProductSkuAttrId());
                        tradeSnapshot.setProductSkuAttrValName(productSkuBean.getProductSkuAttrValName());
                        tradeSnapshot.setSkuPicture(productSkuBean.getSkuPicture());
                        tradeSnapshot.setCreateTime(new Date());
                        tradeSnapshotItems.add(tradeSnapshot);
                    }

                    // 订单信息
                    storeShouldAmount = storeTotalAmount + storeFreightAmount - storeDiscountAmount - couponDiscount;
                    OrderT order = new OrderT();
                    order.setId(orderId);
                    order.setOrderPaymenId(orderPayMenId);
                    order.setOrderStatus(OrderEnums.OrderStatus.UNPAID.getStatus());
                    order.setStoreTId(storeKey);
                    order.setUserTId(sessionId.toString());
                    // 商品数量
                    order.setProductCount(cartItems.size());
                    // 商品总价
                    order.setProductAmountTotal(storeTotalAmount);
                    // 实际付款金额
                    order.setOrderAmountTotal(storeShouldAmount);
                    // 运费
                    order.setFareTotal(storeFreightAmount);
                    // 是否开票
                    order.setIsTax(item.isInvoice());
                    // 发票编号
                    order.setTaxCode(StaticKeys.NULL);
                    // 收货地址（暂时不用）
                    order.setDeliverAddressTId(StaticKeys.NULL);
                    // 物流编号
                    order.setLogisticsCode(StaticKeys.NULL);
                    // 物流名称
                    order.setLogisticsName(StaticKeys.NULL);
                    // 付款方式，0为账户余额，1为支付宝，2为微信，3为银联、首次为待定状态
                    order.setPaymentChannel(PaymentEnums.PaymentChannel.UNDECIDED.getMethod());
                    // 第三方支付交易单号
                    order.setPayTradeCode(StaticKeys.NULL);
                    order.setCreateTime(new Date());
                    // 用户备注
                    order.setUserRemark(item.getUserRemark());
                    // 订单结算时间
                    order.setOrderSettlementTime(new Date());
                    // 是否自营
                    order.setSelf(true);
                    // 使用账户余额
                    order.setAccountBalance(0);
                    // 使用福利金金额
                    order.setBenefits(0);
                    // 第三方支付金额
                    order.setPaymentPlatformMoney(0);
                    // 使用积分数量
                    order.setIntegralAmount(0);
                    // 积分抵扣金额
                    order.setIntegralMoney(0);
                    /**
                     * 收货地址
                     */
                    DeliverAddressT deliverAddress = deliverAddressTRepository.findOneByIdAndUserTId(item.getAddressId(), sessionId.toString());
                    if (deliverAddress != null) {
                        order.setDeliverAddress(deliverAddress.getContacts() + "，" + deliverAddress.getPhone() + "，" + deliverAddress.getProvince() + deliverAddress.getCity() + deliverAddress.getCounty() + deliverAddress.getAddress() + "，" + deliverAddress.getZipCode());
                    }
                    // 店铺优惠
                    order.setStoreDiscount(couponDiscount);
                    // 平台优惠
                    // 注意：此优惠为整个订单的优惠信息
                    order.setPlatformDiscount(couponDiscount);
                    // 发票信息
                    order.setInvoiceContent(StaticKeys.NULL);
                    order.setExpressCode(StaticKeys.NULL);
                    // 未开票时，此字段生效
                    order.setInvoiceStatus(InvoiceEnums.InvoiceStatusApply.APPLY.getStatus());
                    order.setRemoved(false);
                    // 判断是否是首单
                    long orderCount = orderTRepository.countByUserTIdAndFirstOrder(sessionId.toString(), true);
                    if (orderCount == 0) {
                        order.setFirstOrder(true);
                    } else {
                        order.setFirstOrder(false);
                    }
                    orderItems.add(order);
                }
            }
            orderItemTRepository.saveAll(orderItemItems);
            orderTRepository.saveAll(orderItems);
            tradeSnapshotTRepository.saveAll(tradeSnapshotItems);
            userCouponTRepository.saveAll(userCouponItems);
            cartTRepository.deleteAll(delCartItems);
            return Response.success(orderPayMenId, StaticKeys.SUCCESS);
        } catch (Exception e) {
            log.error("保存订单失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("保存订单失败");
        }
    }

    @ApiOperation(value = "取消订单")
    @ApiImplicitParam(name = "id", value = "ID", dataType = "String", required = true)
    @GetMapping(value = "/cancel/{id}")
    @Transactional
    public Object cancelOrder(@PathVariable String id, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            List<OrderT> orderItems = orderTRepository.findByOrderPaymenIdAndUserTIdAndRemoved(id, sessionId.toString(), StaticKeys.REMOVED);
            if (orderItems == null) {
                return Response.badRequest_400("不存在的订单信息，请核实");
            }
            // 更新订单状态
            List<OrderT> updateOrderItems = new ArrayList<>();
            for (OrderT order : orderItems) {
                order.setOrderStatus(OrderEnums.OrderStatus.TRANSACTION_CANCEL.getStatus());
                if (order.isFirstOrder()) {
                    order.setFirstOrder(false);
                }
                updateOrderItems.add(order);
            }
            List<UserCouponT> userCouponItems = userCouponTRepository.findByUserIdAndDataId(sessionId.toString(), id);
            List<UserCouponT> updateUserCouponItems = new ArrayList<>();
            for (UserCouponT bean : userCouponItems) {
                bean.setStatus(false);
                updateUserCouponItems.add(bean);
            }
            orderTRepository.saveAll(updateOrderItems);
            userCouponTRepository.saveAll(updateUserCouponItems);
            return Response.success();
        } catch (Exception e) {
            log.error("取消订单失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("取消订单失败");
        }
    }

    @ApiOperation(value = "获取支付凭证")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", dataType = "String", required = true),
            @ApiImplicitParam(name = "payType", value = "支付类型", dataType = "int", required = true)
    })
    @GetMapping(value = "/certificate/{id}/{payType}")
    @Transactional
    public Object payCertificate(@PathVariable String id, @PathVariable int payType, HttpSession session, HttpServletRequest request) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            UserT userBean = userTRepository.findOneById(sessionId.toString());
            if (userBean == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            List<OrderT> orderItems = orderTRepository.findByOrderPaymenIdAndUserTIdAndRemoved(id, sessionId.toString(), StaticKeys.REMOVED);
            if (orderItems == null) {
                return Response.badRequest_400("不存在的订单信息，请核实");
            }
            int totalFee = 0;
            // 获取总支付金额
            for (OrderT order : orderItems) {
                totalFee += order.getOrderAmountTotal();
            }
            if (payType == PaymentEnums.PaymentChannel.BALANCE.getMethod()) {
                // 余额支付
                if (userBean.getCurBalance() < totalFee) {
                    return Response.badRequest_400("余额不足，无法支付");
                }
                List<OrderT> updateOrderItems = new ArrayList<>();
                    for (OrderT order : orderItems) {
                        // 支付方式
                        order.setPaymentChannel(PaymentEnums.PaymentChannel.BALANCE.getMethod());
                        order.setPayTradeCode(StaticKeys.NULL);
                        order.setOrderStatus(OrderEnums.OrderStatus.PAID.getStatus());
                        updateOrderItems.add(order);
                }

                // 处理用户余额
                int curBalance = userBean.getCurBalance() - totalFee;
                userBean.setCurBalance(curBalance);
                // 记录余额变化历史
                BalanceHistoryT balanceHistory = new BalanceHistoryT();
                balanceHistory.setId(PrimaryKey.get().toString());
                balanceHistory.setBalanceAmountTotal(curBalance);
                balanceHistory.setBalanceStatus(BalanceEnums.BalanceStatus.CONSUMPTION.getStatus());
                balanceHistory.setSubTotal(totalFee);
                balanceHistory.setUserTId(userBean.getId());
                balanceHistory.setRemark("订单：" + id + "消费");
                balanceHistory.setCreateTime(new Date());
                userTRepository.save(userBean);
                balanceHistoryTRepository.save(balanceHistory);
                orderTRepository.saveAll(updateOrderItems);
                Map<String, Object> responseData = new HashMap<>();
                responseData.put("totalFee", totalFee);
                return Response.success(responseData, StaticKeys.SUCCESS);
            } else if (payType == PaymentEnums.PaymentChannel.WECHAT.getMethod()) {
                // 微信支付
                String nonce_str = WXPayUtil.generateUUID();
                Map<String, String> orderData = new HashMap<>();
                orderData.put("appid", wxjsapiPayConfig.getAppID());
                orderData.put("mch_id", wxjsapiPayConfig.getMchID());
                orderData.put("nonce_str", nonce_str);
                orderData.put("body", "ENKI订单:" + id + "支付");
                orderData.put("out_trade_no", id);
                orderData.put("total_fee", String.valueOf(totalFee));
//                String addressId = realIP(request);
                orderData.put("spbill_create_ip", wxjsapiPayConfig.getHostIP());
                orderData.put("notify_url", wxjsapiPayConfig.getNotifyUrl() + "/api/wechat/jsapi");
                orderData.put("trade_type", wxjsapiPayConfig.getTradeType());
                orderData.put("sign_type", wxjsapiPayConfig.getSignType());
                orderData.put("openid", userBean.getOpenid());
                String sign = WXPayUtil.generateSignature(orderData, wxjsapiPayConfig.getKey());
                orderData.put("sign", sign);
                Map<String, String> orderResult = new WXPay(wxjsapiPayConfig).unifiedOrder(orderData);
                if (orderResult.get("return_code").equals("SUCCESS") && orderResult.get("return_msg").equals("OK") && orderResult.get("result_code").equals("SUCCESS")) {
                    // 预支付交易会话标识
                    String prepay_id = orderResult.get("prepay_id").toString();
                    List<OrderT> updateOrderItems = new ArrayList<>();
                    for (OrderT order : orderItems) {
                        // 支付方式
                        order.setPaymentChannel(PaymentEnums.PaymentChannel.WECHAT.getMethod());
                        // 第三方支付交易单号
                        order.setPayTradeCode(prepay_id);
                        updateOrderItems.add(order);
                    }
                    orderTRepository.saveAll(updateOrderItems);
                    String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
                    Map<String, String> payData = new HashMap<>();
                    payData.put("appId", wxjsapiPayConfig.getAppID());
                    payData.put("timeStamp", timeStamp);
                    payData.put("nonceStr", nonce_str);
                    payData.put("package", "prepay_id=" + orderResult.get("prepay_id").toString());
                    payData.put("signType", wxjsapiPayConfig.getSignType());
                    String paySign = WXPayUtil.generateSignature(payData, wxjsapiPayConfig.getKey());
                    // 封装支付参数
                    WXParam wxParam = new WXParam();
                    wxParam.setAppid(wxjsapiPayConfig.getAppID());
                    wxParam.setTimestamp(timeStamp);
                    wxParam.setNonceStr(nonce_str);
                    wxParam.setPackages("prepay_id=" + orderResult.get("prepay_id").toString());
                    wxParam.setSignType(wxjsapiPayConfig.getSignType());
                    wxParam.setSign(paySign);
                    Map<String, Object> responseData = new HashMap<>();
                    responseData.put("wxParam", wxParam);
                    responseData.put("totalFee", totalFee);
                    return Response.success(responseData, StaticKeys.SUCCESS);
                } else {
                    return Response.serverError_500("服务器错误，获取支付信息失败");
                }
            }
            return Response.success();
        } catch (Exception e) {
            log.error("获取支付凭证失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("获取支付凭证失败");
        }
    }

    /**
     * 获取Nginx代理之后的用户真实ip
     *
     * @param request
     * @return
     */
    private static String realIP(HttpServletRequest request) {
        String ipFromNginx = getRemoteHost(request);
        log.info("realIP==========真实用户IP=================>>>>>>>>>>>>>>>>>>" + ipFromNginx);
        if (StringUtils.isNotBlank(ipFromNginx) && !StringUtils.equals("unknown", ipFromNginx)) {
            return ipFromNginx;
        }
        return ipFromNginx;
    }


    private static String getRemoteHost(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        log.info("getIpAddress(HttpServletRequest) - X-Forwarded-For - String ip="
                + ip);
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
                log.info("getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip="
                        + ip);
            }
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
                log.info("getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip="
                        + ip);
            }
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
                log.info("getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip="
                        + ip);
            }
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
                log.info("getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip="
                        + ip);
            }
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
                log.info("getIpAddress(HttpServletRequest) - getRemoteAddr - String ip="
                        + ip);
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }

    private void showParams(HttpServletRequest request) {
        Map<String, String> map = new HashMap<String, String>();
        Enumeration paramNames = request.getParameterNames();
        while (paramNames.hasMoreElements()) {
            String paramName = (String) paramNames.nextElement();
            String[] paramValues = request.getParameterValues(paramName);
            if (paramValues.length == 1) {
                if (paramValues[0].length() != 0) {
                    map.put(paramName, paramValues[0]);
                }
            }
        }
        //打印map所有值
        Set<Map.Entry<String, String>> set = map.entrySet();
        for (Map.Entry entry : set) {
            log.info(entry.getKey() + ":" + entry.getValue());
        }
    }

}
